package io.renren.modules.sys.shiro;

import io.renren.common.session.ProtostuffSerializer;
import io.renren.common.session.SpringSessionConnectionFactory;
import io.renren.common.utils.RedisKeys;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.ShardedJedis;

import java.io.Serializable;

/**
 * shiro session dao
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2017/9/27 21:35
 */
@Component
public class RedisShiroSessionDAO extends EnterpriseCacheSessionDAO {
    /*@Autowired
    private RedisTemplate redisTemplate;*/
    @Autowired
    private SpringSessionConnectionFactory connectionFactory;

    //创建session
    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = super.doCreate(session);
        final String key = RedisKeys.getShiroSessionKey(sessionId.toString());
        setShiroSession(key, session);
        return sessionId;
    }

    //获取session
    @Override
    protected Session doReadSession(Serializable sessionId) {
        Session session = super.doReadSession(sessionId);
        if(session == null){
            final String key = RedisKeys.getShiroSessionKey(sessionId.toString());
            session = getShiroSession(key);
        }
        return session;
    }

    //更新session
    @Override
    protected void doUpdate(Session session) {
        super.doUpdate(session);
        final String key = RedisKeys.getShiroSessionKey(session.getId().toString());
        setShiroSession(key, session);
    }

    //删除session
    @Override
    protected void doDelete(Session session) {
        super.doDelete(session);
        final String key = RedisKeys.getShiroSessionKey(session.getId().toString());
        ShardedJedis jedis =null;
        try {
            jedis = connectionFactory.fetchShardedJedis();
            jedis.del(ProtostuffSerializer.serializeObject(key));
        } finally {
            if (jedis != null){
                jedis.close();
            }
        }
    }

    private Session getShiroSession(String key) {
        //return (Session)redisTemplate.opsForValue().get(key);
        ShardedJedis jedis = null;
        try {
            jedis = connectionFactory.fetchShardedJedis();
            byte[] value = jedis.get(ProtostuffSerializer.serializeObject(key));
            if (value == null){
                return null;
            }
            Session session = ProtostuffSerializer.deserialize(value,SimpleSession.class);
            return session;
        } finally {
            if (jedis != null){
                jedis.close();
            }
        }
    }

    private void setShiroSession(String key, Session session){
        //redisTemplate.opsForValue().set(key, session);
        //60分钟过期
        //redisTemplate.expire(key, 60, TimeUnit.MINUTES);
        ShardedJedis jedis = null;
        try {
            jedis = connectionFactory.fetchShardedJedis();
            jedis.set(ProtostuffSerializer.serializeObject(key),ProtostuffSerializer.serializeObject(session));
            jedis.expire(ProtostuffSerializer.serializeObject(key),1800);
        } finally {
            if (jedis != null){
                jedis.close();
            }
        }
    }
}
